package com.changgou.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.goods.feign.SkuFeign;
import com.changgou.goods.feign.SpuFeign;
import com.changgou.goods.pojo.Sku;
import com.changgou.goods.pojo.Spu;
import com.changgou.order.config.CartMQProperties;
import com.changgou.order.dao.CartItemMapper;
import com.changgou.order.pojo.CartItem;
import com.changgou.order.pojo.OrderItem;
import com.changgou.order.service.CartService;
import com.changgou.order.vo.CartItemDto;
import com.changgou.order.vo.CartSkuVo;
import entity.IdWorker;
import entity.Result;
import entity.TypeEnum;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author ljh
 * @version 1.0
 * @date 2021/1/5 12:02
 * @description 标题
 * @package com.changgou.order.service.impl
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private SpuFeign spuFeign;

    @Override
    public void add(Integer num, Long id, String username) {
        if(num<=0){
            //删除掉
            redisTemplate.boundHashOps("Cart_" + username).delete(id);
            return;
        }
        //1.根据商品的sku的ID 获取商品的数据
        //1.1 在changgou-service-goods-api中创建feign接口 sku,spu
        //1.2 需要在changgou-service-goods微服务中实现feign接口
        //1.3 订单微服务添加依赖
        //1.4 订单微服务启动类中 启用feignclients 注入 使用
        Sku sku = skuFeign.findById(id).getData();

        //2.将商品的数据 进行转换到POJO（orderItem）中
        OrderItem orderItem = new OrderItem();

        //设置一级 二级 三级分类的ID  需要先通过sku的ID 获取到spu的ID 再通过spu的ID 获取spu的数据
        Spu spu = spuFeign.findById(sku.getSpuId()).getData();
        orderItem.setCategoryId1(spu.getCategory1Id());
        orderItem.setCategoryId2(spu.getCategory2Id());
        orderItem.setCategoryId3(spu.getCategory3Id());
        orderItem.setImage(sku.getImage());
        orderItem.setPrice(sku.getPrice());
        orderItem.setSkuId(id);
        orderItem.setSpuId(sku.getSpuId());
        orderItem.setName(sku.getName());
        orderItem.setNum(num);
        orderItem.setMoney(num*sku.getPrice());//应付金额
        orderItem.setPayMoney(num*sku.getPrice());//实付金额
        //3.将数据存到hash类型的redis中 存储到购物车中 1.起步依赖 2. 配置host:port 3.注入redisTemplate
        //hset key field value
        redisTemplate.boundHashOps("Cart_" + username).put(id, orderItem);
    }

    @Override
    public List<OrderItem> list(String username) {
        return redisTemplate.boundHashOps("Cart_" + username).values();
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CartMQProperties cartMQProperties;

    @Autowired
    private CartItemMapper cartItemMapper;

    @Override
    public void addToRedis(Integer num, Long id, String username) {

        //先从redis中获取购买的商品的数据
        String cartSkuStr = stringRedisTemplate.boundValueOps(String.valueOf(id)).get();
        //如果没有数据，从数据库找（goods微服中获取ksu的数据）
        if (StringUtils.isEmpty(cartSkuStr)) {
            Result<Sku> result = skuFeign.findById(id);
            Sku sku = result.getData();
            //1.添加到购物车 修改redis
            CartSkuVo cartSkuVo = new CartSkuVo();
            BeanUtils.copyProperties(sku, cartSkuVo);
            cartSkuVo.setSkuId(id);

            //设置购买的商品价格等信息
            stringRedisTemplate.boundValueOps(String.valueOf(id)).set(JSON.toJSONString(cartSkuVo));
            stringRedisTemplate.boundValueOps(String.valueOf(id)).expire(7, TimeUnit.DAYS);//随机数
        }
        //设置购买数量 是字符串请注意
        stringRedisTemplate.boundHashOps("Cartx_" + username).put(String.valueOf(id), String.valueOf(num));
        //设置7天超时
        stringRedisTemplate.boundHashOps("Cartx_" + username).expire(7, TimeUnit.DAYS);

        //2.发送消息 修改数据库
        CartItemDto cartItem = new CartItemDto();
        cartItem.setCartSkuId(id);
        cartItem.setNum(num);
        cartItem.setId(idWorker.nextId() + "");
        cartItem.setCreateTime(new Date());
        cartItem.setUpdateTime(cartItem.getUpdateTime());
        //新增操作
        cartItem.setType(TypeEnum.ADD.getTypeValue());

        rabbitTemplate.convertAndSend(cartMQProperties.getExchange(), cartMQProperties.getRouting(), JSON.toJSONString(cartItem));

    }

    //删除商品
    @Override
    public void deletex(Long id, String username) {
        stringRedisTemplate.boundHashOps("Cartx_" + username).delete(String.valueOf(id));
        CartItemDto cartItem = new CartItemDto();
        cartItem.setId(id.toString());
        //删除
        cartItem.setType(TypeEnum.DELETE.getTypeValue());
        rabbitTemplate.convertAndSend(cartMQProperties.getExchange(), cartMQProperties.getRouting(), JSON.toJSONString(cartItem));
    }

    //更新
    @Override
    public void updatex(Integer num, Long id, String username) {
        String cartSkuStr = stringRedisTemplate.boundValueOps(String.valueOf(id)).get();

        if (StringUtils.isEmpty(cartSkuStr)) {
            Result<Sku> result = skuFeign.findById(id);
            Sku sku = result.getData();
            //1.添加到购物车 修改redis
            CartSkuVo cartSkuVo = new CartSkuVo();
            BeanUtils.copyProperties(sku, cartSkuVo);
            cartSkuVo.setSkuId(id);

            //设置购买的商品价格等信息
            stringRedisTemplate.boundValueOps(id.toString()).set(JSON.toJSONString(cartSkuVo));
            stringRedisTemplate.boundValueOps(id.toString()).expire(7, TimeUnit.DAYS);
        }
        //设置购买数量
        stringRedisTemplate.boundHashOps("Cartx_" + username).put(id.toString(), String.valueOf(num));
        //设置7天超时
        stringRedisTemplate.boundHashOps("Cartx_" + username).expire(7, TimeUnit.DAYS);

        //2.发送消息 修改数据库的数量
        CartItemDto cartItem = new CartItemDto();
        cartItem.setCartSkuId(id);
        //设置数量
        cartItem.setNum(num);
        cartItem.setUpdateTime(cartItem.getUpdateTime());
        //更新的操作类型
        cartItem.setType(TypeEnum.UPDATE.getTypeValue());

        rabbitTemplate.convertAndSend(cartMQProperties.getExchange(), cartMQProperties.getRouting(), JSON.toJSONString(cartItem));
    }


    @Override
    public List<OrderItem> listx(String username) {
        List<OrderItem> orderItemList = new ArrayList<OrderItem>();
        //根据用户名获取所有的ID
        Set ids = stringRedisTemplate.boundHashOps("Cartx_" + username).keys();
        if (ids != null && ids.size() > 0) {
            for (Object id : ids) {
                String idstr = (String) id;
                //根据ID获取cartSku对象
                String s = stringRedisTemplate.boundValueOps(idstr).get();

                CartSkuVo cartSkuVo = JSON.parseObject(s, CartSkuVo.class);
                //获取数量
                Integer num = Integer.parseInt((String)stringRedisTemplate.boundHashOps("Cartx_" + username).get(id));
                //封装
                OrderItem orderItem = new OrderItem();
                orderItem.setImage(cartSkuVo.getImage());
                orderItem.setNum(num);
                orderItem.setPrice(cartSkuVo.getPrice());
                orderItem.setMoney(orderItem.getPrice() * num);
                orderItem.setPayMoney(orderItem.getPrice() * num);
                orderItem.setSkuId(Long.valueOf(idstr));
                orderItemList.add(orderItem);
            }
        } else {
            //从数据库查询
            CartItem record = new CartItem();
            record.setUsername(username);
            List<CartItem> cartItemList = cartItemMapper.select(record);
            if (cartItemList != null) {
                for (CartItem cartItem : cartItemList) {

                    //skuId的值
                    Long id = cartItem.getCartSkuId();
                    //设置购买数量
                    stringRedisTemplate.boundHashOps("Cartx_" + username).put(id.toString(), String.valueOf(cartItem.getNum()));
                    //设置7天超时
                    stringRedisTemplate.boundHashOps("Cartx_" + username).expire(7, TimeUnit.DAYS);


                    String cartSkuStr = stringRedisTemplate.boundValueOps(id.toString()).get();
                    if (StringUtils.isEmpty(cartSkuStr)) {
                        //这里可以优化 批量查询
                        Result<Sku> result = skuFeign.findById(id);
                        Sku sku = result.getData();
                        //1.添加到购物车 修改redis
                        CartSkuVo cartSkuVo = new CartSkuVo();
                        BeanUtils.copyProperties(sku, cartSkuVo);
                        cartSkuVo.setSkuId(id);

                        //设置购买的商品价格等信息
                        stringRedisTemplate.boundValueOps(id.toString()).set(JSON.toJSONString(cartSkuVo));
                        stringRedisTemplate.boundValueOps(id.toString()).expire(7, TimeUnit.DAYS);
                    }
                }
            }
            //todo 将数据转换之后存储到 orderItemList  再返回

        }

        return orderItemList;
    }

}
